React Refs - REACT教程

React Refs

React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。

这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance ),这样就可以确保在任何时间总是拿到正确的实例。

在 React 中,Refs(引用)提供了一种访问 DOM 元素或组件实例的方法。使用 Refs 可以直接操作 DOM 元素或获取子组件实例,适用于处理焦点、文本选择、媒体播放、触发强制动画或集成第三方 DOM 库等场景。

使用方法

使用 React.createRef 或 useRef 来创建和访问 refs。

React.createRef 通常用于类组件,而 useRef 是一个 Hook,通常用于函数组件。

此外,在事件处理函数中绑定 this 也可以通过类属性语法来避免每次渲染时都创建一个新的函数。

  • 创建 Ref :在类组件的构造函数中使用 React.createRef 创建 ref 对象,并将其赋值给组件实例的一个属性。
  • 绑定 Ref :在 render 方法中,将 ref 对象绑定到需要引用的 DOM 元素上。
  • 访问 Ref :在组件的其它方法中,通过 this.myInputRef.current 访问绑定的 DOM 元素,可以操作该元素的属性和方法。

完整实例

你可以通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用,实例如下:

示例代码
classMyComponentextendsReact.Component{constructor(props){super(props);this.myInputRef=React.createRef();}handleClick=()=>{//使用原生的 DOM API 获取焦点this.myInputRef.current.focus();}render(){return(<div><inputtype="text"ref={this.myInputRef}/><inputtype="button"value="点我输入框获取焦点"onClick={this.handleClick}/></div>);}}

实例中,我们获取了输入框的支撑实例的引用,子点击按钮后输入框获取焦点。

我们也可以使用 getDOMNode()方法获取 DOM 元素


创建 Refs

React 提供了 React.createRef 方法来创建 refs。

示例代码
importReact from'react';importReactDOM from'react-dom';classMyComponentextendsReact.Component{constructor(props){super(props);this.myRef=React.createRef();}componentDidMount(){this.myRef.current.focus();}render(){return<input type="text"ref={this.myRef}/>;}}constroot=ReactDOM.createRoot(document.getElementById("root"));// 渲染 MyComponent 组件root.render(<MyComponent/>);

回调 Refs

另一种创建 refs 的方式是使用回调函数。这种方式在 React 16.3 之前很常见,现在更推荐使用 React.createRef。

示例代码
classMyComponentextendsReact.Component{constructor(props){super(props);this.setMyRef=element=>{this.myRef=element;};}componentDidMount(){if(this.myRef){this.myRef.focus();}}render(){return<input type="text"ref={this.setMyRef}/>;}}constroot=ReactDOM.createRoot(document.getElementById("root"));// 渲染 MyComponent 组件root.render(<MyComponent/>);

使用 Refs 访问 DOM 元素

通过 Refs 可以直接访问并操作 DOM 元素。

示例代码
classMyComponentextendsReact.Component{constructor(props){super(props);this.myRef=React.createRef();}handleClick=()=>{this.myRef.current.style.backgroundColor='yellow';};render(){return(<div><input type="text"ref={this.myRef}/><button onClick={this.handleClick}>Change Background</button></div>);}}constroot=ReactDOM.createRoot(document.getElementById("root"));// 渲染 MyComponent 组件root.render(<MyComponent/>);

使用 Refs 访问子组件实例

Refs 还可以用于访问子组件的实例方法或属性。

示例代码
classChildComponentextendsReact.Component{focusInput=()=>{this.inputRef.current.focus();};constructor(props){super(props);this.inputRef=React.createRef();}render(){return<input type="text"ref={this.inputRef}/>;}}classParentComponentextendsReact.Component{constructor(props){super(props);this.childRef=React.createRef();}handleClick=()=>{this.childRef.current.focusInput();};render(){return(<div><ChildComponent ref={this.childRef}/><button onClick={this.handleClick}>Focus Child Input</button></div>);}}constroot=ReactDOM.createRoot(document.getElementById("root"));// 渲染 MyComponent 组件root.render(<MyComponent/>);

使用 useRef Hook(函数组件)

在函数组件中,可以使用 useRef Hook 创建 refs。

示例代码
importReact,{useRef}from'react';importReactDOM from'react-dom';constMyComponent=()=>{constinputRef=useRef(null);consthandleClick=()=>{inputRef.current.focus();};return(<div><input type="text"ref={inputRef}/><button onClick={handleClick}>Focus Input</button></div>);};constroot=ReactDOM.createRoot(document.getElementById("root"));// 渲染 MyComponent 组件root.render(<MyComponent/>);

小结

  • 创建 Refs :在类组件中使用 React.createRef ,在函数组件中使用 useRef Hook。
  • 访问 DOM 元素 :通过 refs 直接访问并操作 DOM 元素。
  • 访问子组件实例 :通过 refs 访问子组件的实例方法或属性。
  • 自定义暴露的实例值 :使用 useImperativeHandle forwardRef 自定义子组件暴露给父组件的实例值。
  • 并发模式中的 Refs :Refs 在并发模式中依然正常工作,可以与 useTransition 等并发模式相关的 Hook 结合使用。